#include "service.h"

Service::Service()
{

}

bool Service::expressionCalculate(QString str, double &res)
{
    if (!Util::checkExpression(str)) {
        return false;
    }
    //清空栈
    numStack.clear();
    operatorStack.clear();
    //#作为栈底
    operatorStack.push('#');
    double top;	//访问操作符栈顶时，获取栈顶元素
    double a, b;	//访问数字
    char oper;		//记录字符串中的操作符
    int len = str.length();
    int start = 0;	//遇到操作数 指向操作符首位
    int end;		//下个操作符位置

//    char numStr[MAX_NUM_LENGTH];
    QString numStr;
    //遍历字符串
    while (true) {
        //start = len 时，认为当前为#号
        if (start == len || Util::isOperator(str[start].toLatin1())) {
            oper = start == len ? '#' : str[start].toLatin1();
            top = operatorStack.top();
            //printf("\n运算符：%c\n", (char)top);
            //与操作符栈顶比较
            char c = OperatorTable::precede((char)top, oper);
            if (c == '<') {	//比栈顶优先级高
                operatorStack.push(oper);
                //读取下一个
                start++;
            }
            else if (c == '=') {//优先级相同
                //消除
                operatorStack.pop();
                //读取下一个
                start++;
            }
            else if (c == '>') {//栈顶优先级更高
                //弹出两个数 需要判断是否成功
                if(!numStack.isEmpty()){
                    b = numStack.pop();
                }else{
                    return false;
                }
                if(!numStack.isEmpty()){
                    a = numStack.pop();
                }else{
                    return false;
                }
                //弹出操作符
                top = operatorStack.pop();
                //计算的结果入栈
                numStack.push(OperatorTable::operate(a, (char)top, b));
                //这里当前输入的操作符，做下次判断，不需要再读取了
            }
            else {	//表达式非法
                //printf("表达式非法\n %c 和 %c\n", (char)top, (char)oper);
                return false;
            }
            if (operatorStack.isEmpty())	//运算结束
                break;
        }
        else {	//截取操作数
            end = start;
            while (end < len && !Util::isOperator(str[end].toLatin1())) {
                end++;
            }
            numStr = str.mid(start, end - start);
            //结束位
            if (Util::isNumStr(numStr)) {
//                qDebug()<<Util::strToDouble(numStr)<<endl;
                numStack.push(Util::strToDouble(numStr));
            }
            else {	//非数字
                return false;
            }
            //继续
            start = end;
        }
    }

    //得到结果
    if (numStack.size() != 1)
        return false;
    res = numStack.top();
    return true;
}

Complex Service::add(Complex c1, Complex c2)
{
    return Complex(c1.getReal() + c2.getReal(), c1.getImag() + c2.getImag());
}

Complex Service::subtract(Complex c1, Complex c2)
{
    return Complex(c1.getReal() - c2.getReal(), c1.getImag() - c2.getImag());
}

Complex Service::multiply(Complex c1, Complex c2)
{
    int r = c1.getReal() * c2.getReal() - c1.getImag() * c2.getImag();
    int i = c1.getImag() * c2.getReal() + c1.getReal() * c2.getImag();
    return Complex(r, i);
}

Complex Service::divide(Complex c1, Complex c2)
{
    int a = c1.getReal(), b = c1.getImag(), c = c2.getReal(), d = c2.getImag();
    int r = (a * c + b * d) / (c * c + d * d);
    int i = (b * c - a * d) / (c * c + d * d);
    return Complex(r, i);
}

Matrix Service::add(Matrix m1, Matrix m2)
{
    int nums[m1.m][MAX_LEN];
    for(int i = 0; i < m1.m; i++){
        for(int j = 0; j < m1.n; j++){
            nums[i][j] = m1.matrix[i][j] + m2.matrix[i][j];
        }
    }
    return Matrix(m1.m, m1.n, nums);
}

Matrix Service::sub(Matrix m1, Matrix m2)
{
    int nums[m1.m][MAX_LEN];
    for(int i = 0; i < m1.m; i++){
        for(int j = 0; j < m1.n; j++){
            nums[i][j] = m1.matrix[i][j] - m2.matrix[i][j];
        }
    }
    return Matrix(m1.m, m1.n, nums);
}

Matrix Service::mul(Matrix m1, Matrix m2)
{
    //结果矩阵的行列
    int m = m1.m, n = m2.n;
    int nums[m][MAX_LEN];
    int sum, cur;
    for(int i = 0; i < m1.m; i++){
        //m1 的行向量 与 m2 列向量的乘积
        for(int j = 0; j < m2.n; j++){
            sum = 0;
            cur = 0;
            while(cur < m1.n){
                sum += m1.matrix[i][cur] * m2.matrix[cur][j];
                cur++;
            }
            nums[i][j] = sum;
//            qDebug()<<sum<<endl;
        }
    }
    return Matrix(m, n, nums);
}

void Service::dfs(int index, QList<QString> nums, QList<QString> list)
{
    if(index == nums.size()){
        QString str("[");
        for(int i = 0; i < list.size(); i++){
            str.append(list[i]);
            if(i != list.size() - 1){
                str.append(",");
            }
        }
        str.append("]");
        resultList.push_back(str);
        return;
    }
    dfs(index + 1, nums, list);
    list.push_back(nums[index]);
    dfs(index + 1, nums, list);
    list.removeLast();
}

QStringList Service::subset(QList<QString> nums)
{
    //清空
    resultList.clear();
    //生成子集
    QList<QString> list;
    dfs(0, nums, list);
    return resultList;
}
